/*
 * EP-Tracing System : a tool to trace mountain hike.           .kNNx
 * Copyright (C) 2009  Raffaello Brondi                         'KNNNk
 *                                                             ,XNNNl
 * This program is free software:                             ,XNN0'
 * you can redistribute it and/or modify                     ,XNNx.
 * it under the terms of the                                'XNNl
 * GNU General Public License                              .KNN:                     ..
 * as published by                                        .0NNo                    .ONNO.
 * the Free Software Foundation,                          xNNN.  :dkd,            .KNNNN;
 * either version 3 of the License, or                   :NNNK ;XNNNNNo          ,KNNNX:
 * (at your option) any later version.                   xNNNNcXNNNNNNk         cNNNNx.
 *                                                       ,XNNNNNNNNNNX'       .xNNNK;
 *                                                        .lKNNNNNNNK'       :KNNNo
 *                                                          ;kNNNNNKxl;'.'l0NNNk.
 * This program is distributed in                          .'  .:xXNNNNNNNNNNNO,
 * the hope that it will be useful,                       :NNXd'   ,oONNNNNNk,
 * but WITHOUT ANY WARRANTY;                              xNNNNN0c.    .;;,.
 * without even the implied warranty of                   kNNNNNNNXd'
 * MERCHANTABILITY or                                     xNNNNNNNNNNOc.
 * FITNESS FOR A PARTICULAR PURPOSE.                      xNNNNNNNNNNNNXd.
 * See the GNU General Public License                     ONNNN0.,o0NNNNNNl
 * for more details.                                      0NNNNd    kNNNNNX.
 *                                                        KNNNNl   oNNNNNXc
 *                                                       .XNNNN:  dNNNNNx.
 * You should have received a copy                       .XNNNN; lNNNNO'
 * of the GNU General Public License                     .XNNNN; 'dxo'
 * along with this program.                              .XNNNN;
 * If not, see <http://www.gnu.org/licenses/>.            0NNNN:
 *                                                        kNNNNc
 *                                                        oNNNNd
 *                                                        ;NNNN0
 * Contact: rbrondi@gmail.com                             .XNNNN;
 *                                                         kNNNNd
 *                                                         .coo:.
 */
package EP.UI;

import EP.FileSystemManager;
import EP.GPS.GPSDataWrapper;
import EP.UI.Compass.Compass;
import EP.UI.Compass.EPHLoader;
import EP.UI.Trace.TracerState;
import EP.UI.Trace.TripSetup;
import EP.Utils;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;
import javax.microedition.location.LocationProvider;
import javax.microedition.midlet.*;

/**
 * @author Raffaello Brondi
 */
public class EPTS extends MIDlet implements CommandListener {

    /** A static reference to Display object. */
    private static Display display = null;
    /** A Reference to TouristData. */
    private GPSDataWrapper gdw = null;
    //private Trip trip;
    private List main;
    private TripSetup tripSetup;
    private TracerState ts;
    private Command closeApp;
    private boolean midletPaused = false;
    private Compass compass;
    private EPHLoader ephLoader;

    public EPTS() {
        super();
    }

    /**
     * Exits MIDlet.
     */
    public void exitMIDlet() {
        switchDisplayable(null, null);
        destroyApp(true);
        notifyDestroyed();
    }

    /**
     * Called when MIDlet is started.
     * Checks whether the MIDlet have been already started and initialize/starts or resumes the MIDlet.
     */
    public void startApp() {
        if (midletPaused) {
            //resumeMIDlet();
        } else {
            initialize();
        }
        //startMIDlet();

        midletPaused = false;
    }

    /**
     * Called when MIDlet is paused.
     */
    public void pauseApp() {
        midletPaused = true;
    }

    /**
     * Called to signal the MIDlet to terminate.
     * @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.
     */
    public void destroyApp(boolean unconditional) {
    }

    /**
     * Switches a current displayable in a display. The <code>display</code> instance is taken from <code>getDisplay</code> method. This method is used by all actions in the design for switching displayable.
     * @param alert the Alert which is temporarily set to the display; if <code>null</code>, then <code>nextDisplayable</code> is set immediately
     * @param nextDisplayable the Displayable to be set
     */
    public void switchDisplayable(Alert alert, Displayable nextDisplayable) {
        if (alert == null) {
            display.setCurrent(nextDisplayable);
        } else {
            display.setCurrent(alert, nextDisplayable);
        }
    }

    private void initialize() {
        display = Display.getDisplay(this);
        if (Utils.isLocationApiSupported() && Utils.isFCApiSupported()) {
            this.tripSetup = new TripSetup();
            this.closeApp = new Command("Exit", Command.EXIT, 0);
            SplashScreen splashScreen = new SplashScreen("/EP_rebeldia.png", this.getList());
            splashScreen.setTitle("EP-TS");
            switchDisplayable(null, splashScreen);
        } else {
            Messages.showApiNotSupported();
        }
    }

    /**
     * Getter method for Display reference.
     *
     * @return reference to Display object.
     */
    public static Display getDisplay() {
        return display;
    }

    /**
     * Returns an initiliazed instance of list component.
     * @return the initialized component instance
     */
    public List getList() {
        if (this.main == null) {
            this.main = new List("Ep tracing sistem", Choice.IMPLICIT);
            try {
                Image image = Image.createImage("/foot.png");
                this.main.append("Start new trace session", image);
            } catch (java.io.IOException e) {
                e.printStackTrace();
                this.main.append("Start new trace session", null);
            }
            //this.main.append("Start new Trac session", null);
            try {
                Image image = Image.createImage("/needle.png");
                this.main.append("Load trip", image);
            } catch (java.io.IOException e) {
                e.printStackTrace();
                this.main.append("Load trip", null);
            }
            //this.main.append("Load trip", null);
            this.main.addCommand(this.closeApp);
            this.main.setCommandListener(this);
            this.main.setFitPolicy(Choice.TEXT_WRAP_DEFAULT);
            this.main.setSelectedFlags(new boolean[]{false, false});
        }
        return this.main;
    }

    /**
     * Performs an action assigned to the selected list element in the list component.
     */
    public void listAction() {
        String selectedString = this.main.getString(getList().getSelectedIndex());
        if (selectedString != null) {
            if (selectedString.equals("Start new trace session")) {
                if (this.tripSetup == null) {
                    this.tripSetup = new TripSetup();
                }
                this.tripSetup.setCommandListener(this);
                switchDisplayable(null, this.tripSetup);
            } else if (selectedString.equals("Load trip")) {
                if (this.ephLoader == null) {
                    this.ephLoader = new EPHLoader(this);
                }
                this.ephLoader.reset();
                switchDisplayable(null, this.ephLoader);
                //FileBrowser b = new FileBrowser();
            }
        }
    }

    public void commandAction(Command command, Displayable displayable) {
        if (displayable.getTitle() != null && displayable.getTitle().equals("EP-TS")) {
            this.switchDisplayable(null, getList());
        } else if (displayable == this.main) {
            if (command == List.SELECT_COMMAND) {
                this.listAction();
            } else if (command.equals(this.closeApp)) {
                this.exitMIDlet();
            }
        } else if (displayable == this.tripSetup) {
            if (command.equals(this.tripSetup.getCloseCommand())) {
                this.switchDisplayable(null, this.main);
            } else if (command.equals(this.tripSetup.getStartCommand())) {
                this.switchDisplayable(null, Messages.showLooking4Provider());
                this.startGPSMonitoring();
            }
        } else if (displayable == this.ts) {
            this.gdw.stop();
            if (command == this.ts.getSaveCommand()) {
                this.saveTrip();
                switchDisplayable(new Alert("save the points"), this.main);
            } else if (command == this.ts.getAbortCommand()) {
                FileSystemManager.getInstance().deleteTrip();
                switchDisplayable(null, this.main);
            }
            this.ts = null;
        } else if (displayable == this.compass) {
            if (command == this.compass.getBackCommand()) {
                switchDisplayable(null, this.main);
            }
        } else if (displayable == this.ephLoader) {
            if (command == this.ephLoader.getExitCommand()) {
                switchDisplayable(null, this.main);
            }
            if (command == this.ephLoader.getDetailsCommand()) {
                this.ephLoader.showEPHDetails();
            }
            if (command == this.ephLoader.getLoadCommand()) {
                this.ephLoader.load();
            }

            if (command == List.SELECT_COMMAND) {
                this.ephLoader.openFolder();
            }

        }else if (displayable.getTitle().equals("Hike deteils")) {
            this.switchDisplayable(null, this.ephLoader);
        }

    }

    private void startGPSMonitoring() {
        final LocationProvider lp = Utils.getLocationProvider(this.tripSetup.getTripCriteria());
        FileSystemManager.getInstance().setPath(this.tripSetup.getStorage() + System.currentTimeMillis() + ".eph");
        if (lp == null) {
            this.switchDisplayable(Messages.showNoProvider4Criteria(), this.tripSetup);
        } else {
            if (this.gdw == null) {
                this.gdw = new GPSDataWrapper();
            }
            Thread initGDW = new Thread() {

                public void run() {
                    gdw.initializeGDW(lp);
                }
            };
            initGDW.start();
            if (this.ts == null) {
                this.ts = new TracerState(this.tripSetup, this);
            }
            FileSystemManager.getInstance().startTrip();
            this.gdw.setTracerState(this.ts);
            switchDisplayable(null, this.ts);
        }
    }

    private void saveTrip() {
        System.out.println("save the trip");
        this.ts.closeTrip();
    }
}


